#include "networkmanager.h"

NetworkManager::NetworkManager(QObject *parent) : QObject(parent)
{
    tcpSocket = new QTcpSocket(this);
    udpSocket = new QUdpSocket(this);
    
    // 初始化接收缓冲区
    receiveBuffer.clear();
    
    // 连接TCP socket信号
    connect(tcpSocket, &QTcpSocket::connected, this, [this]() {
        LOG_INFO("TCP连接已建立");
        emit connectionStatusChanged(true);
    });
    
    connect(tcpSocket, &QTcpSocket::disconnected, this, [this]() {
        LOG_INFO("TCP连接已断开");
        emit connectionStatusChanged(false);
    });
    
    connect(tcpSocket, &QTcpSocket::readyRead, this, [this]() {
        QByteArray data = tcpSocket->readAll();
        processReceivedData(data);
    });
    
    connect(tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
            this, [this]() {
        QString errorMsg = "TCP错误: " + tcpSocket->errorString();
        LOG_ERROR(errorMsg);
        emit errorOccurred(errorMsg);
    });
    
    // 连接UDP socket信号
    connect(udpSocket, &QUdpSocket::readyRead, this, [this]() {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;
            
            udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
            LOG_INFO(QString("从 %1:%2 接收到UDP数据").arg(sender.toString()).arg(senderPort));
            
            processReceivedData(datagram);
        }
    });
}

NetworkManager::~NetworkManager()
{
    disconnectFromHost();
}

bool NetworkManager::connectToHost(const QString &host, quint16 port)
{
    if (isConnected()) {
        LOG_WARNING("已经连接到服务器，先断开当前连接");
        disconnectFromHost();
    }
    
    LOG_INFO(QString("尝试连接到 %1:%2").arg(host).arg(port));
    tcpSocket->connectToHost(host, port);
    
    // 等待连接建立，最多等待5秒
    if (!tcpSocket->waitForConnected(5000)) {
        LOG_ERROR(QString("连接超时: %1").arg(tcpSocket->errorString()));
        return false;
    }
    
    return true;
}

void NetworkManager::disconnectFromHost()
{
    if (tcpSocket->state() != QAbstractSocket::UnconnectedState) {
        tcpSocket->disconnectFromHost();
        tcpSocket->waitForDisconnected();
    }
}

bool NetworkManager::sendData(MessageType type, const QJsonObject &data)
{
    if (!isConnected()) {
        LOG_ERROR("发送失败: 未连接到服务器");
        return false;
    }
    
    QString typeStr = messageTypeToString(type);
    LOG_INFO(QString("准备发送消息类型: %1 (枚举值: %2)").arg(typeStr).arg(static_cast<int>(type)));
    
    QJsonObject message;
    message["type"] = typeStr;
    message["data"] = data;
    
    QJsonDocument doc(message);
    QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
    
    LOG_INFO(QString("JSON数据大小: %1字节").arg(jsonData.size()));
    
    // 添加包头和包尾
    QByteArray packet;
    packet.append("HH_START");  // 包头标识
    packet.append(jsonData);
    packet.append("HH_END");    // 包尾标识
    
    LOG_INFO(QString("完整数据包大小: %1字节").arg(packet.size()));
    
    qint64 bytesSent = tcpSocket->write(packet);
    if (bytesSent != packet.size()) {
        LOG_ERROR(QString("发送数据不完整: 已发送 %1/%2 字节").arg(bytesSent).arg(packet.size()));
        return false;
    }
    
    LOG_INFO(QString("成功发送 %1 类型消息, %2 字节").arg(typeStr).arg(bytesSent));
    
    return true;
}

bool NetworkManager::isConnected() const
{
    return tcpSocket->state() == QAbstractSocket::ConnectedState;
}

void NetworkManager::processReceivedData(const QByteArray &data)
{
    // 在这里存储接收到的数据
    receiveBuffer.append(data);
    
    LOG_INFO(QString("接收到数据包，大小: %1字节，缓冲区总大小: %2字节").arg(data.size()).arg(receiveBuffer.size()));
    
    // 循环处理所有完整的数据包
    int startPos = 0;
    while ((startPos = receiveBuffer.indexOf("HH_START", startPos)) != -1) {
        int endPos = receiveBuffer.indexOf("HH_END", startPos);
        
        if (endPos == -1) {
            // 没有找到包尾，数据包不完整，等待更多数据
            LOG_INFO("数据包不完整，等待更多数据");
            break;
        }
        
        // 提取JSON数据部分
        QByteArray jsonData = receiveBuffer.mid(startPos + 8, endPos - startPos - 8);
        
        LOG_INFO(QString("找到完整数据包，大小: %1字节").arg(jsonData.size()));
        
        QJsonParseError parseError;
        QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
        
        if (parseError.error != QJsonParseError::NoError) {
            LOG_ERROR(QString("JSON解析错误: %1").arg(parseError.errorString()));
            // 跳过此数据包，继续处理后面的
            startPos = endPos + 7; // "HH_END"的长度是7
            continue;
        }
        
        QJsonObject message = doc.object();
        
        if (!message.contains("type") || !message.contains("data")) {
            LOG_WARNING("收到格式错误的消息");
            // 跳过此数据包，继续处理后面的
            startPos = endPos + 7;
            continue;
        }
        
        QString typeStr = message["type"].toString();
        MessageType type = stringToMessageType(typeStr);
        QJsonObject dataObj = message["data"].toObject();
        
        LOG_INFO(QString("解析消息类型: %1，转换为枚举: %2").arg(typeStr).arg(static_cast<int>(type)));
        
        emit dataReceived(type, dataObj);
        
        // 处理完这个数据包，从缓冲区中移除
        receiveBuffer.remove(0, endPos + 7);
        
        // 重置起始位置，从缓冲区开头继续查找
        startPos = 0;
    }
    
    // 如果缓冲区过大（例如超过10MB），可能存在问题，清空缓冲区
    if (receiveBuffer.size() > 10 * 1024 * 1024) {
        LOG_WARNING("接收缓冲区过大，清空缓冲区");
        receiveBuffer.clear();
    }
}

QString NetworkManager::messageTypeToString(MessageType type)
{
    switch (type) {
    case MessageType::Connect:
        return "Connect";
    case MessageType::Authenticate:
        return "Authenticate";
    case MessageType::ScreenData:
        return "ScreenData";
    case MessageType::MouseEvent:
        return "MouseEvent";
    case MessageType::KeyboardEvent:
        return "KeyboardEvent";
    case MessageType::AudioData:
        return "AudioData";
    case MessageType::AudioFormat:
        return "AudioFormat";
    case MessageType::SystemInfo:
        return "SystemInfo";
    case MessageType::Disconnect:
        return "Disconnect";
    case MessageType::Heartbeat:
        return "Heartbeat";
    case MessageType::Error:
        return "Error";
    case MessageType::FileSendRequest:
        return "FileSendRequest";
    case MessageType::FileSendData:
        return "FileSendData";
    case MessageType::FileSendFinish:
        return "FileSendFinish";
    case MessageType::FileSendAck:
        return "FileSendAck";
    default:
        return "Unknown";
    }
}

MessageType NetworkManager::stringToMessageType(const QString &typeStr)
{
    if (typeStr == "Connect") return MessageType::Connect;
    if (typeStr == "Authenticate") return MessageType::Authenticate;
    if (typeStr == "ScreenData") return MessageType::ScreenData;
    if (typeStr == "MouseEvent") return MessageType::MouseEvent;
    if (typeStr == "KeyboardEvent") return MessageType::KeyboardEvent;
    if (typeStr == "AudioData") return MessageType::AudioData;
    if (typeStr == "AudioFormat") return MessageType::AudioFormat;
    if (typeStr == "SystemInfo") return MessageType::SystemInfo;
    if (typeStr == "Disconnect") return MessageType::Disconnect;
    if (typeStr == "Heartbeat") return MessageType::Heartbeat;
    if (typeStr == "Error") return MessageType::Error;
    if (typeStr == "FileSendRequest") return MessageType::FileSendRequest;
    if (typeStr == "FileSendData") return MessageType::FileSendData;
    if (typeStr == "FileSendFinish") return MessageType::FileSendFinish;
    if (typeStr == "FileSendAck") return MessageType::FileSendAck;
    
    LOG_WARNING(QString("未知消息类型: %1").arg(typeStr));
    return MessageType::Error;
} 